package cn.tedu.tmall.basic.dao.repository.impl;

import cn.tedu.tmall.basic.dao.repository.IDistrictCacheRepository;
import cn.tedu.tmall.basic.pojo.po.DistrictPO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

/**
 * 处理省市区数据的缓存访问实现类
 *
 * @author java@tedu.cn
 * @version 3.0
 **/
@Slf4j
@Repository
public class DistrictCacheRepositoryImpl implements IDistrictCacheRepository {

    // jedis
    @Autowired
    private RedisTemplate<String, Serializable> redisTemplate;





    @Override
    public List<DistrictPO> listByParent(Long parentId) {
        log.debug("开始处理【根据父级查询子级地区列表】的缓存数据访问，父级地区ID：{}", parentId);
        String key = KEY_PREFIX_LIST_BY_PARENT + parentId;
        long start = 0;
        long end = -1;
        ListOperations<String, Serializable> opsForList = redisTemplate.opsForList();
        List range = opsForList.range(key, start, end);
        return range;
    }

    @Override
    public void saveDict(Long parentId, List<DistrictPO> districtPOS) {
        String key = KEY_PREFIX_LIST_BY_PARENT + parentId; // dict:list-by-parent:0 dict:list-by-parent:1
        ListOperations<String, Serializable> opsForList = redisTemplate.opsForList();
        for (DistrictPO districtPO : districtPOS) {
            opsForList.rightPush(key,districtPO);
        }
        SetOperations<String, Serializable> opsForSet = redisTemplate.opsForSet();
        opsForSet.add(KEY_ALL_KEYS,key);
    }

    @Override
    public void deleteAll() {
        //基础命令 比如删除key,比如续期key 设置key过期时间 redisTemplate
        //如果我们要对具体的数据类型的value进行操作,才需要opsFor...
        //方案1 keys * 去查询 KEY_PREFIX_LIST_BY_PARENT 为开头的所有key
        //原始命令为 keys district:list-by-parent:*
        //问 能用么? 答 能用吧 keys* 是不建议在线上使用,因为reids是单线程,keys*如果数据量过大,
        //会阻塞别的命令的操作. 如果这个redis是你独享的,可以这么玩,如果是共享的比如购物车也在使用这个redis
        //就有可能影响购物车.
        //方案2 核心的问题是我们不知道应该具体删哪个key?
        // 1 我们能不能把这个key给记住呢?
        //   key 保存到redis set 存起来
        //什么时候存 ,预热的时候
        //Set<String> keys = redisTemplate.keys(KEY_PREFIX_LIST_BY_PARENT + "*");
        //redisTemplate.delete(keys);
        SetOperations<String, Serializable> opsForSet = redisTemplate.opsForSet();
        Set members = opsForSet.members(KEY_ALL_KEYS);
        redisTemplate.delete(members);
    }

}
